/*
 * =====================================================================================
 *
 *       Filename:  Command.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2015年02月27日 22时35分06秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  LiuYi (), swliuyi@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <limits.h>
#include <iostream>
#include  <tr1/memory>
#include  <vector>

using namespace std;
class Receiver
{
    public:
        void Action()
        {
            cout<<"Action"<<endl;
        }
};

class Command
{
    protected:
        tr1::shared_ptr<Receiver> m_receiver;
    public:
        Command(Receiver * receiver)
        {
            m_receiver.reset(receiver);
        }
        virtual void Execute() = 0;
        virtual ~Command(){}
};

class ConcreteCommand : public Command
{
    public:
        ConcreteCommand(Receiver * receiver):Command(receiver){}
        void Execute()
        {
            m_receiver->Action();
        }
        virtual ~ConcreteCommand(){}
};

class Invoker
{
    private:
        vector<tr1::shared_ptr<Command> > m_commands;
    public:
        void AddCommand(Command * command)
        {
            tr1::shared_ptr<Command> tmp(command);
            m_commands.push_back(tmp);
            cout<<tmp.use_count()<<endl;
        }
        void RemoveCommand(Command * command)
        {
            for( vector<tr1::shared_ptr<Command> >::reverse_iterator i = m_commands.rbegin();  i != m_commands.rend() ; i++ )
            {
                if( i->get() == command )
                {
                    m_commands.erase(i.base());
                }
            }
        }
        void ExecuteCommand()
        {
            for( size_t i = 0 ; i < m_commands.size() ; i++ )
            {
                m_commands[i]->Execute();
            }
        }
};

int main(int argc, char *argv[])
{
    Receiver * r = new Receiver();
    Command * c1 = new ConcreteCommand(r);
    Command * c2 = new ConcreteCommand(r);
    Invoker * i = new Invoker();
    i->AddCommand(c1);
    i->AddCommand(c2);
    i->ExecuteCommand();
    i->RemoveCommand(c1);
    i->ExecuteCommand();
    delete i;
}


